package org.jeecg.modules.activiti.web;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.collect.Lists;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.activiti.bpmn.model.Activity;
import org.activiti.engine.*;
import org.activiti.engine.history.HistoricIdentityLink;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.impl.interceptor.Command;
import org.activiti.engine.impl.interceptor.CommandContext;
import org.activiti.engine.impl.persistence.entity.ExecutionEntity;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.pvm.process.ProcessDefinitionImpl;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Comment;
import org.activiti.engine.task.IdentityLink;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.oa.enums.PendingSubStateEnum;
import org.jeecg.common.oa.utils.OaMessageUtils;
import org.jeecg.common.oa.utils.OaPendingUtils;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.util.JwtUtil;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.modules.activiti.entity.ActBusiness;
import org.jeecg.modules.activiti.entity.ActZprocess;
import org.jeecg.modules.activiti.enums.ResultEnum;
import org.jeecg.modules.activiti.enums.StatusEnum;
import org.jeecg.modules.activiti.service.IActBusinessService;
import org.jeecg.modules.activiti.service.IActZprocessService;
import org.jeecg.modules.activiti.service.Impl.ActZprocessServiceImpl;
import org.jeecg.modules.activiti.vo.ActivitiConstant;
import org.jeecg.modules.activiti.vo.Assignee;
import org.jeecg.modules.activiti.vo.HistoricTaskVo;
import org.jeecg.modules.activiti.vo.TaskVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotEmpty;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author pmc
 */
@Slf4j
@RestController
@RequestMapping("/actTask")
@Transactional
@Api(tags = "流程")
public class ActTaskController {

    @Autowired
    private TaskService taskService;

    @Autowired
    private HistoryService historyService;

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private ManagementService managementService;

    @Autowired
    private IActZprocessService actZprocessService;

    @Autowired
    private IActBusinessService actBusinessService;
    @Autowired
    ISysBaseAPI sysBaseAPI;

    /*代办列表*/
    @AutoLog(value = "流程-代办列表")
    @ApiOperation(value = "流程-代办列表", notes = "代办列表")
    @RequestMapping(value = "/todoList", method = RequestMethod.GET)
    public Result<Object> todoList(@ApiParam(value = "任务名称") String name,
                                   @ApiParam(value = "任务分类") String categoryId,
                                   @ApiParam(value = "优先级") Integer priority,
                                   @ApiParam(value = "创建开始时间") String createTime_begin,
                                   @ApiParam(value = "创建结束时间") String createTime_end,
                                   HttpServletRequest request) {
        List<TaskVo> list = new ArrayList<>();
        LoginUser sysUser = JwtUtil.getLoginUser();
        String userId = sysUser.getUsername();
        TaskQuery query = taskService.createTaskQuery().taskCandidateOrAssigned(userId);
        // 多条件搜索
        query.orderByTaskPriority().desc();
        query.orderByTaskCreateTime().desc();
        if (StrUtil.isNotBlank(name)) {
            query.taskNameLike("%" + name + "%");
        }
        if (StrUtil.isNotBlank(categoryId)) {
            query.taskCategory(categoryId);
        }
        if (priority != null) {
            query.taskPriority(priority);
        }
        if (StrUtil.isNotBlank(createTime_begin)) {
            Date start = DateUtil.parse(createTime_begin);
            query.taskCreatedAfter(start);
        }
        if (StrUtil.isNotBlank(createTime_end)) {
            Date end = DateUtil.parse(createTime_end);
            query.taskCreatedBefore(DateUtil.endOfDay(end));
        }
        //流程类型
        String type = request.getParameter("type");
        if (StrUtil.isNotBlank(type)) {
            List<String> deployment_idList = actBusinessService.deploymentIdListByType(type);
            if (deployment_idList.size() == 0) {
                query.deploymentIdIn(Lists.newArrayList(""));
            } else {
                query.deploymentIdIn(deployment_idList);
            }
        }
        String searchVal = request.getParameter("searchVal");
        if (StrUtil.isNotBlank(searchVal)) {
            //搜索标题、申请人
            List<LoginUser> usersByName = sysBaseAPI.getUsersByName(searchVal);
            List<String> uNames = null;
            if (usersByName.size() == 0) {
                uNames = Lists.newArrayList("");
            } else {
                uNames = usersByName.stream().map(u -> u.getUsername()).collect(Collectors.toList());
            }
            List<ActBusiness> businessList = actBusinessService.list(new LambdaQueryWrapper<ActBusiness>()
                    .like(ActBusiness::getTitle, searchVal) //标题查询
                    .or().in(ActBusiness::getUserId, uNames)
            );
            if (businessList.size() > 0) {
                // 定义id
                List<String> pids = businessList.stream().filter(act -> act.getProcInstId() != null).map(act -> act.getProcInstId()).collect(Collectors.toList());
                query.processInstanceIdIn(pids);
            } else {
                query.processInstanceIdIn(Lists.newArrayList(""));
            }
        }
        List<Task> taskList = query.list();
        // 是否需要业务数据
        String needData = request.getParameter("needData");
        // 转换vo
        taskList.forEach(e -> {
            TaskVo tv = new TaskVo(e);

            // 关联委托人
            if (StrUtil.isNotBlank(tv.getOwner())) {
                String realname = sysBaseAPI.getUserByName(tv.getOwner()).getRealname();
                tv.setOwner(realname);
            }
            List<IdentityLink> identityLinks = runtimeService.getIdentityLinksForProcessInstance(tv.getProcInstId());
            for (IdentityLink ik : identityLinks) {
                // 关联发起人
                if ("starter".equals(ik.getType()) && StrUtil.isNotBlank(ik.getUserId())) {
                    tv.setApplyer(sysBaseAPI.getUserByName(ik.getUserId()).getRealname());
                }
            }
            // 关联流程信息
            ActZprocess actProcess = actZprocessService.getById(tv.getProcDefId());
            if (actProcess != null) {
                tv.setProcessName(actProcess.getName());
                tv.setRouteName(actProcess.getRouteName());
            }
            // 关联业务key
            ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(tv.getProcInstId()).singleResult();
            tv.setBusinessKey(pi.getBusinessKey());
            ActBusiness actBusiness = actBusinessService.getById(pi.getBusinessKey());
            if (actBusiness != null) {
                tv.setTableId(actBusiness.getTableId());
                tv.setTableName(actBusiness.getTableName());
                tv.setTitle(actBusiness.getTitle());
                tv.setStatus(actBusiness.getStatus());
                tv.setResult(actBusiness.getResult());
                if (StrUtil.equals(needData, "true")) { // 需要业务数据
                    Map<String, Object> applyForm = actBusinessService.getApplyForm(actBusiness.getTableId(), actBusiness.getTableName());
                    tv.setDataMap(applyForm);
                }
            }
            list.add(tv);
        });
        return Result.ok(list);
    }

    /*代办列表*/
    @AutoLog(value = "流程-查询详情")
    @ApiOperation(value = "流程-查询详情", notes = "查询详情")
    @RequestMapping(value = "/getById", method = RequestMethod.GET)
    public Result<Object> getById(@ApiParam(value = "ID") String id) {
        Task task = taskService.createTaskQuery().taskId(id).singleResult();
        TaskVo tv = new TaskVo();
        if (task != null){
            // 转换vo
            tv = new TaskVo(task);
            // 关联委托人
            if (StrUtil.isNotBlank(tv.getOwner())) {
                String realname = sysBaseAPI.getUserByName(tv.getOwner()).getRealname();
                tv.setOwner(realname);
            }
             List<IdentityLink> identityLinks = runtimeService.getIdentityLinksForProcessInstance(tv.getProcInstId());
            for (IdentityLink ik : identityLinks) {
                // 关联发起人
                if ("starter".equals(ik.getType()) && StrUtil.isNotBlank(ik.getUserId())) {
                    tv.setApplyer(sysBaseAPI.getUserByName(ik.getUserId()).getRealname());
                }
            }
            // 关联流程信息
            ActZprocess actProcess = actZprocessService.getById(tv.getProcDefId());
            if (actProcess != null) {
                tv.setProcessName(actProcess.getName());
                tv.setRouteName(actProcess.getRouteName());
            }
            // 关联业务key
            ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(tv.getProcInstId()).singleResult();
            tv.setBusinessKey(pi.getBusinessKey());
            ActBusiness actBusiness = actBusinessService.getById(pi.getBusinessKey());
            if (actBusiness != null) {
                tv.setTableId(actBusiness.getTableId());
                tv.setTableName(actBusiness.getTableName());
                tv.setTitle(actBusiness.getTitle());
                tv.setStatus(actBusiness.getStatus());
                tv.setResult(actBusiness.getResult());
            }
        } else {
            return Result.error("");
        }
        return Result.ok(tv);
    }

    /*获取可返回的节点*/
    @AutoLog(value = "流程-获取可返回的节点")
    @ApiOperation(value = "流程-获取可返回的节点", notes = "获取可返回的节点")
    @RequestMapping(value = "/getBackList/{procInstId}", method = RequestMethod.GET)
    public Result<Object> getBackList(@PathVariable String procInstId) {
        List<HistoricTaskVo> list = new ArrayList<>();
        List<HistoricTaskInstance> taskInstanceList = historyService.createHistoricTaskInstanceQuery()
                .processInstanceId(procInstId)
                .finished()
                .list();

        List<HistoricTaskVo> finalList = list;
        taskInstanceList.forEach(e -> {
            HistoricTaskVo htv = new HistoricTaskVo(e);
            finalList.add(htv);
        });
        List<Task> tasks = taskService.createTaskQuery().processInstanceId(procInstId).list();
// 增加非空判断，避免空指针异常
        if (tasks != null && !tasks.isEmpty() && "销售领导".equals(tasks.get(0).getName())) {
            // 使用Stream过滤，只保留name为项目管理和技术员的元素
            list = list.stream()
                    .filter(htv -> "销售".equals(htv.getName()))
                    .collect(Collectors.toList());
        }
        if (tasks != null && !tasks.isEmpty() && "项目管理".equals(tasks.get(0).getName())) {
            // 使用Stream过滤，只保留name为项目管理和技术员的元素
            list = list.stream()
                    .filter(htv -> "销售领导".equals(htv.getName()) )
                    .collect(Collectors.toList());
        }
        if (tasks != null && !tasks.isEmpty() && "技术员".equals(tasks.get(0).getName())) {
            // 使用Stream过滤，只保留name为项目管理和技术员的元素
            list = list.stream()
                    .filter(htv -> "技术组长".equals(htv.getName()) || "技术组长".equals(htv.getName()))
                    .collect(Collectors.toList());
        }
        if (tasks != null && !tasks.isEmpty() && "技术组长".equals(tasks.get(0).getName())) {
            // 使用Stream过滤，只保留name为项目管理和技术员的元素
            list = list.stream()
                    .filter(htv -> "项目管理".equals(htv.getName()) || "技术员".equals(htv.getName()))
                    .collect(Collectors.toList());
        }

        if (tasks != null && !tasks.isEmpty() && "技术组长复核".equals(tasks.get(0).getName())) {
            // 使用Stream过滤，只保留name为项目管理和技术员的元素
            list = list.stream()
                    .filter(htv -> "项目管理".equals(htv.getName()) || "技术员".equals(htv.getName()))
                    .collect(Collectors.toList());
        }

        if (tasks != null && !tasks.isEmpty() && "采购员".equals(tasks.get(0).getName())) {
            // 使用Stream过滤，只保留name为项目管理和技术员的元素
            list = list.stream()
                    .filter(htv -> "项目管理".equals(htv.getName()) || "技术组长复核".equals(htv.getName()))
                    .collect(Collectors.toList());
        }
        if (tasks != null && !tasks.isEmpty() && "采购领导".equals(tasks.get(0).getName())) {
            // 使用Stream过滤，只保留name为项目管理和技术员的元素
            list = list.stream()
                    .filter(htv -> "项目管理".equals(htv.getName()) || "技术组长复核".equals(htv.getName()) || "采购员".equals(htv.getName() ))
                    .collect(Collectors.toList());
        }
        if (tasks != null && !tasks.isEmpty() && "成本".equals(tasks.get(0).getName())) {
            // 使用Stream过滤，只保留name为项目管理和技术员的元素
            list = list.stream()
                    .filter(htv -> "技术组长复核".equals(htv.getName()) || "技术员".equals(htv.getName())
                            || "采购员".equals(htv.getName())
                            || "成本".equals(htv.getName())
                            || "采购领导".equals(htv.getName()
                    ))
                    .collect(Collectors.toList());
        }
        if (tasks != null && !tasks.isEmpty() && "成本员".equals(tasks.get(0).getName())) {
            // 使用Stream过滤，只保留name为项目管理和技术员的元素
            list = list.stream()
                    .filter(htv -> "技术组长复核".equals(htv.getName()) || "技术员".equals(htv.getName())
                            || "采购员".equals(htv.getName())
                            || "采购领导".equals(htv.getName()
                    ))
                    .collect(Collectors.toList());
        }
        if (tasks != null && !tasks.isEmpty() && "财务员".equals(tasks.get(0).getName())) {
            // 使用Stream过滤，只保留name为项目管理和技术员的元素
            list = list.stream()
                    .filter(htv -> "技术组长复核".equals(htv.getName()) || "技术员".equals(htv.getName())
                            || "采购员".equals(htv.getName())
                            || "成本员".equals(htv.getName())
                            || "成本领导".equals(htv.getName())
                            || "采购领导".equals(htv.getName()
                    ))
                    .collect(Collectors.toList());
        }
        if (tasks != null && !tasks.isEmpty() && "财务经理".equals(tasks.get(0).getName())) {
            // 使用Stream过滤，只保留name为项目管理和技术员的元素
            list = list.stream()
                    .filter(htv -> "技术组长复核".equals(htv.getName()) || "技术员".equals(htv.getName())
                            || "采购员".equals(htv.getName())
                            || "成本员".equals(htv.getName())
                            || "财务".equals(htv.getName())
                            || "成本领导".equals(htv.getName())
                            || "采购领导".equals(htv.getName()
                    ))
                    .collect(Collectors.toList());
        }
        if (tasks != null && !tasks.isEmpty() && "财务总监".equals(tasks.get(0).getName())) {
            // 使用Stream过滤，只保留name为项目管理和技术员的元素
            list = list.stream()
                    .filter(htv -> "技术组长复核".equals(htv.getName()) || "技术员".equals(htv.getName())
                            || "采购员".equals(htv.getName())
                            || "成本员".equals(htv.getName())
                            || "财务".equals(htv.getName())
                            || "成本领导".equals(htv.getName())
                            || "采购领导".equals(htv.getName()
                    ))
                    .collect(Collectors.toList());
        }

        System.out.println(tasks+"打印1当前任务信息");
        System.out.println("查看历史节点"+list);
        // 去重
        LinkedHashSet<String> set = new LinkedHashSet<String>(list.size());
        List<HistoricTaskVo> newList = new ArrayList<>();

        list.forEach(e -> {
            if (set.add(e.getName())) {
                newList.add(e);
            }
        });
        // 颠倒列表顺序
        Collections.reverse(newList);
        return Result.ok(newList);
    }

    /*任务节点审批 驳回至发起人*/
    @AutoLog(value = "流程-任务节点审批 驳回至发起人")
    @ApiOperation(value = "流程-任务节点审批 驳回至发起人", notes = "任务节点审批 驳回至发起人")
    @RequestMapping(value = "/back", method = RequestMethod.POST)
    public Result<Object> back(@ApiParam("任务id") @RequestParam String id,
                               @ApiParam("流程实例id") @RequestParam String procInstId,
                               @ApiParam("意见评论") @RequestParam(required = false) String comment,
                               @ApiParam("是否发送站内消息") @RequestParam(defaultValue = "false") Boolean sendMessage,
                               @ApiParam("是否发送短信通知") @RequestParam(defaultValue = "false") Boolean sendSms,
                               @ApiParam("是否发送邮件通知") @RequestParam(defaultValue = "false") Boolean sendEmail) {


        if (StrUtil.isBlank(comment)) {
            comment = "";
        }
        taskService.addComment(id, procInstId, comment);
        OaPendingUtils.sendCompletePending(id, PendingSubStateEnum.NOT_AGREE.getStatus());
        ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(procInstId).singleResult();
        // 删除流程实例
        runtimeService.deleteProcessInstance(procInstId, "backed");
        ActBusiness actBusiness = actBusinessService.getById(pi.getBusinessKey());
        actBusiness.setStatus(StatusEnum.STATUS_FINISH.getStatus());
        actBusiness.setResult(ResultEnum.RESULT_FAIL.getStatus());
        actBusinessService.updateById(actBusiness);
        // 异步发消息
        LoginUser sysUser = JwtUtil.getLoginUser();
        LoginUser toUser = sysBaseAPI.getUserByName(actBusiness.getUserId());
        actZprocessService.sendMessage(actBusiness.getId(), sysUser, toUser, ActivitiConstant.MESSAGE_BACK_CONTENT,
                String.format("您的 【%s】 申请已被驳回！", actBusiness.getTitle()), sendMessage, sendSms, sendEmail);
        OaMessageUtils.sendCompleteMessage(sysUser, toUser, String.format("您的 【%s】 申请已被驳回！", actBusiness.getTitle()));
        OaPendingUtils.sendCompletePending(id, PendingSubStateEnum.OVERRULE.getStatus());

        // 记录实际审批人员
        actBusinessService.insertHI_IDENTITYLINK(IdUtil.simpleUUID(),
                ActivitiConstant.EXECUTOR_TYPE_b, sysUser.getUsername(), id, procInstId);
        //修改业务表的流程字段
        actBusinessService.updateBusinessStatus(actBusiness.getTableName(), actBusiness.getTableId(), actBusiness.getResult(), "驳回");
        return Result.ok("操作成功");
    }

    /*流程流转历史*/
    @AutoLog(value = "流程-流程流转历史")
    @ApiOperation(value = "流程-流程流转历史", notes = "流程流转历史")
    @RequestMapping(value = "/historicFlow/{id}", method = RequestMethod.GET)
    public Result<Object> historicFlow(@ApiParam("实例Id") @PathVariable String id) {
        List<HistoricTaskVo> list = new ArrayList<>();
        List<HistoricTaskInstance> taskList = historyService.createHistoricTaskInstanceQuery()
                .processInstanceId(id).orderByHistoricTaskInstanceEndTime().asc().list();
        System.out.println(taskList+"插卡所欲历史");
        // 转换vo
        taskList.forEach(e -> {
            HistoricTaskVo htv = new HistoricTaskVo(e);
            List<Assignee> assignees = new ArrayList<>();
            // 关联分配人（委托用户时显示该人）
            if (StrUtil.isNotBlank(htv.getAssignee())) {
                String assignee = sysBaseAPI.getUserByName(htv.getAssignee()).getRealname();
                String owner = sysBaseAPI.getUserByName(htv.getOwner()).getRealname();
                assignees.add(new Assignee(assignee + "(受" + owner + "委托)", true));
            }
            List<HistoricIdentityLink> identityLinks = historyService.getHistoricIdentityLinksForTask(e.getId());
            System.out.println(e.getId()+"傻逼东西");
            // 获取实际审批用户id
            List<String> userIds_b = actBusinessService.findUserIdByTypeAndTaskId(ActivitiConstant.EXECUTOR_TYPE_b, e.getId());
            List<String> userIds_p = actBusinessService.findUserIdByTypeAndTaskId(ActivitiConstant.EXECUTOR_TYPE_p, e.getId());
            for (HistoricIdentityLink hik : identityLinks) {
                // 关联候选用户（分配的候选用户审批人）
                if (ActivitiConstant.EXECUTOR_candidate.equals(hik.getType()) && StrUtil.isNotBlank(hik.getUserId())) {
                    String username = sysBaseAPI.getUserByName(hik.getUserId()).getRealname();
                    Assignee assignee = new Assignee(username, false);
                    System.out.println("我是你妈啊"+assignee);
                    /*审批过的标记一下，前端标颜色用*/
                    System.out.println(hik.getUserId()+"呵呵");
                    System.out.println(userIds_p+"呵1呵");
                    if (CollectionUtil.contains(userIds_b, hik.getUserId()) || CollectionUtil.contains(userIds_p, hik.getUserId())) {
                        assignee.setIsExecutor(true);
                    }
                    assignees.add(assignee);
                }
            }
            htv.setAssignees(assignees);
            // 关联审批意见
            List<Comment> comments = taskService.getTaskComments(htv.getId(), "comment");
            if (comments != null && comments.size() > 0) {
                htv.setComment(comments.get(0).getFullMessage());
            }
            list.add(htv);
        });
        return Result.ok(list);
    }

    @RequestMapping(value = "/pass", method = RequestMethod.POST)
    @AutoLog(value = "流程-任务节点审批通过")
    @ApiOperation(value = "任务节点审批通过")
    public Result<Object> pass(@ApiParam("任务id") @RequestParam String id,
                               @ApiParam("流程实例id") @RequestParam String procInstId,
                               @ApiParam("下个节点审批人") @RequestParam(required = false) String assignees,
                               @ApiParam("优先级") @RequestParam(required = false) Integer priority,
                               @ApiParam("意见评论") @RequestParam(required = false) String comment,
                               @ApiParam("是否发送站内消息") @RequestParam(defaultValue = "false") Boolean sendMessage,
                               @ApiParam("是否发送短信通知") @RequestParam(defaultValue = "false") Boolean sendSms,
                               @ApiParam("是否发送邮件通知") @RequestParam(defaultValue = "false") Boolean sendEmail) throws Exception {

        if (StrUtil.isBlank(comment)) {
            comment = "";
        }
        taskService.addComment(id, procInstId, comment);
        ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(procInstId).singleResult();
        Task task = taskService.createTaskQuery().taskId(id).singleResult();
        System.out.println(task+"打印当前任务信息");
        if (StrUtil.isNotBlank(task.getOwner()) && !("RESOLVED").equals(task.getDelegationState().toString())) {
            // 未解决的委托任务 先resolve
            String oldAssignee = task.getAssignee();
            taskService.resolveTask(id);
            taskService.setAssignee(id, oldAssignee);
        }
// 假设已获取当前任务ID和流程实例ID

        String processInstanceId = "当前流程实例ID";

        List<HistoricTaskInstance> taskList = historyService.createHistoricTaskInstanceQuery()
                .processInstanceId(procInstId).taskId(task.getId()).orderByHistoricTaskInstanceEndTime().asc().list();
        System.out.println("查看这是什么消息"+taskList);

        List<Map>  lis1t = actBusinessService.findHis(task.getId());
        List<Map> lis1t2lis1t2 = actBusinessService.findHisPass(task.getId());

        System.out.println("历史审批记录: " + lis1t2lis1t2);
        LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        System.out.println(loginUser.getUsername()+"当前账户");
// 先判断集合是否为空
        if (lis1t2lis1t2 == null || lis1t2lis1t2.isEmpty()) {
            System.out.println("没有历史审批记录");
            // 没有历史记录，继续后续流程
        } else {
            // 遍历所有历史审批记录
            for (Map history : lis1t2lis1t2) {
                // 检查Map中是否包含USER_ID_键，避免NullPointerException
                if (history.containsKey("user_id_")) {
                    System.out.println(history.get("user_id_").toString()+"是否存在");
                    String userId = history.get("user_id_").toString();
                    // 判断当前用户是否已审批
                    if (userId.equals(loginUser.getUsername())) {
                        return Result.error("您当前已审批，请等待另一个人审批");
                    }
                } else {
                    System.out.println("历史记录中不包含USER_ID_字段");
                }
            }
        }

// 继续其他业务逻辑...

        /*会签思路：
        act_hi_identitylink记录着审批历史 ActivitiConstant.EXECUTOR_TYPE_p 标识审批通过
        1、节点设置中增加人数字段，表示需要多少人通过这个任务节点才通过
        2、此处查询审批历史，查看当前节点的审批情况，符合预设的人数调用 taskService.complete(id); 完成该节点任务
        否则只记录审批数据，不完成该任务节点
        3、会有的问题：
            1、如此，审批过的人代办中还会看到这条任务，需要标识自己审批过，但是这条任务自己不能再审了  或 能再审，但是再审记得把之前审批过的记录删掉
            2、下一个节点的审批人只能最后通过的人选择才有效
            3、如果下一个节点是会签，指定下一节点的审批人的数量必须不小于节点预设数量
            其他问题，待暴露
          */
        //把进行中的待办设置为已办
        OaPendingUtils.sendCompletePending(id, PendingSubStateEnum.AGREE.getStatus());

        ActBusiness actBusiness = actBusinessService.getById(pi.getBusinessKey());
        //修改业务表的流程字段
        actBusinessService.updateBusinessStatus(actBusiness.getTableName(), actBusiness.getTableId(), actBusiness.getResult(), "审批中-" + task.getTaskDefinitionKey() + "-" + task.getName());
        /*完成任务*/
        if(lis1t.size() == lis1t2lis1t2.size()+1){
            taskService.complete(id);

        }

        List<Task> tasks = taskService.createTaskQuery().processInstanceId(procInstId).list();
        // 判断下一个节点
        if (tasks != null && tasks.size() > 0) {
            for (Task t : tasks) {
                if (StrUtil.isBlank(assignees)) {
                    // 如果下个节点未分配审批人为空 取消结束流程
                    List<LoginUser> users = actZprocessService.getNode(t.getTaskDefinitionKey()).getUsers();
                    if (users == null || users.size() == 0) {
                        runtimeService.deleteProcessInstance(procInstId, "canceled-审批节点未分配审批人，流程自动中断取消");
                        actBusiness.setStatus(StatusEnum.STATUS_CANCELED.getStatus());
                        actBusiness.setResult(ResultEnum.RESULT_TO_SUBMIT.getStatus());
                        actBusinessService.updateById(actBusiness);
                        //修改业务表的流程字段
                        actBusinessService.updateBusinessStatus(actBusiness.getTableName(), actBusiness.getTableId(), actBusiness.getResult(), "审批异常-" + task.getTaskDefinitionKey() + "-" + task.getName() + "-审批节点未分配审批人，流程自动中断取消");

                        break;
                    } else {
                        // 避免重复添加
                        List<String> list = actBusinessService.selectIRunIdentity(t.getId(), ActivitiConstant.EXECUTOR_candidate);
                        if (list == null || list.size() == 0) {
                            // 分配了节点负责人分发给全部
                            for (LoginUser user : users) {
                                taskService.addCandidateUser(t.getId(), user.getUsername());
                                // 异步发消息
                                actZprocessService.sendActMessage(loginUser, user, actBusiness, task.getName(), sendMessage, sendSms, sendEmail);
                            }
                            taskService.setPriority(t.getId(), task.getPriority());
                            OaPendingUtils.sendRemindPendingList(loginUser, users, actBusiness.getTitle(), t.getId());
                        }
                    }
                } else {
                    // 避免重复添加
                    List<String> list = actBusinessService.selectIRunIdentity(t.getId(), ActivitiConstant.EXECUTOR_candidate);
                    if (list == null || list.size() == 0) {
                        List<LoginUser> users = new ArrayList<>();
                        for (String assignee : assignees.split(CommonConstant.DEFAULT_SEPARATOR)) {
                            taskService.addCandidateUser(t.getId(), assignee);
                            // 异步发消息
                            LoginUser user = sysBaseAPI.getUserByName(assignee);
                            actZprocessService.sendActMessage(loginUser, user, actBusiness, task.getName(), sendMessage, sendSms, sendEmail);
                            taskService.setPriority(t.getId(), priority);
                            users.add(user);
                        }
                        OaPendingUtils.sendRemindPendingList(loginUser, users, actBusiness.getTitle(), t.getId());
                    }
                }
            }
        } else {
            actBusiness.setStatus(StatusEnum.STATUS_FINISH.getStatus());
            actBusiness.setResult(ResultEnum.RESULT_PASS.getStatus());
            actBusinessService.updateById(actBusiness);
            // 异步发消息
            LoginUser user = sysBaseAPI.getUserByName(actBusiness.getUserId());
            actZprocessService.sendMessage(actBusiness.getId(), loginUser, user, ActivitiConstant.MESSAGE_PASS_CONTENT,
                    String.format("您的 【%s】 申请已通过！", actBusiness.getTitle()), sendMessage, sendSms, sendEmail);
            OaMessageUtils.sendCompleteMessage(loginUser, user, String.format("您的 【%s】 申请已通过！", actBusiness.getTitle()));
            OaPendingUtils.sendCompletePending(id, PendingSubStateEnum.AGREE.getStatus());
            //修改业务表的流程字段
            actBusinessService.updateBusinessStatus(actBusiness.getTableName(), actBusiness.getTableId(), actBusiness.getResult(), "审批通过");
            pushMessage("报价系统待办事项2待处理",null,user.getUsername(),"http://10.10.90.100:70/quotation/");
        }
        // 记录实际审批人员
        actBusinessService.insertHI_IDENTITYLINK(IdUtil.simpleUUID(),
                ActivitiConstant.EXECUTOR_TYPE_p, loginUser.getUsername(), id, procInstId);
        return Result.ok("操作成功");
    }
    /**
     * 企业微信消息推送内部应用接口URL,部署服务器无外网,中转一次
     */
    private final static String MESSAGE_PUSH_URL = "http://10.0.0.140:12880/landai/sys/thirdApp/pushWechatEnterpriseMessage";
    @Data
    public class WechatEnterpriseMessageVo {

        @NotEmpty(message = "推送标签为空")
        private String title;

        @NotEmpty(message = "推送内容为空")
        private String content;

        @NotEmpty(message = "推送用户为空")
        private String toUser;

        private String url;

        @NotEmpty(message = "秘钥为空")
        private String secret;

    }
    private void pushMessage(String title, String content, String toUser, String url) {
        try {
            // 消息推送
            WechatEnterpriseMessageVo vo = new WechatEnterpriseMessageVo();
            vo.setTitle(title);
            vo.setContent(content);
            vo.setToUser(toUser);
            vo.setUrl("http://10.10.90.100:70/quotation/");
            vo.setSecret("3a57a50640ba40f7a9e94b455ce4e764");

            String res = HttpUtil.post(MESSAGE_PUSH_URL, JSONObject.toJSONString(vo), 2000);
        } catch (Exception e) {
        }
    }
    @RequestMapping(value = "/delegate", method = RequestMethod.POST)
    @ApiOperation(value = "委托他人代办")
    @AutoLog(value = "流程-委托他人代办")
    public Result<Object> delegate(@ApiParam("任务id") @RequestParam String id,
                                   @ApiParam("委托用户id") @RequestParam String userId,
                                   @ApiParam("流程实例id") @RequestParam String procInstId,
                                   @ApiParam("意见评论") @RequestParam(required = false) String comment,
                                   @ApiParam("是否发送站内消息") @RequestParam(defaultValue = "false") Boolean sendMessage,
                                   @ApiParam("是否发送短信通知") @RequestParam(defaultValue = "false") Boolean sendSms,
                                   @ApiParam("是否发送邮件通知") @RequestParam(defaultValue = "false") Boolean sendEmail) {

        if (StrUtil.isBlank(comment)) {
            comment = "";
        }
        LoginUser sysUser = JwtUtil.getLoginUser();
        taskService.addComment(id, procInstId, comment);
        taskService.delegateTask(id, userId);
        taskService.setOwner(id, sysUser.getUsername());
        ActBusiness actBusiness = actBusinessService.getOne(new LambdaQueryWrapper<ActBusiness>().eq(ActBusiness::getProcInstId, procInstId).last("limit 1"));
        LoginUser toUser = sysBaseAPI.getUserByName(userId);
        // 异步发消息
        actZprocessService.sendMessage(actBusiness.getId(), sysUser, toUser, ActivitiConstant.MESSAGE_DELEGATE_CONTENT,
                String.format("您有一个来自 %s 的委托需要处理！", sysUser.getRealname()), sendMessage, sendSms, sendEmail);

        OaPendingUtils.sendRemindPending(sysUser, toUser, String.format("您有一个来自 %s 的委托需要处理！", sysUser.getRealname()), id);

//        OaMessageUtils.sendCompleteMessage(sysUser, toUser, String.format("您有一个来自 %s 的委托需要处理！", actBusiness.getTitle()));
//        OaPendingUtils.sendCompletePending(id, PendingSubStateEnum.OVERRULE.getStatus());
        return Result.ok("操作成功");
    }

    @RequestMapping(value = "/backToTask", method = RequestMethod.POST)
    @ApiOperation(value = "任务节点审批驳回至指定历史节点")
    @AutoLog(value = "流程-任务节点审批驳回至指定历史节点")
    public Result<Object> backToTask(@ApiParam("任务id") @RequestParam String id,
                                     @ApiParam("驳回指定节点key") @RequestParam String backTaskKey,
                                     @ApiParam("流程实例id") @RequestParam String procInstId,
                                     @ApiParam("流程定义id") @RequestParam String procDefId,
                                     @ApiParam("原节点审批人") @RequestParam(required = false) String assignees,
                                     @ApiParam("优先级") @RequestParam(required = false) Integer priority,
                                     @ApiParam("意见评论") @RequestParam(required = false) String comment,
                                     @ApiParam("是否发送站内消息") @RequestParam(defaultValue = "false") Boolean sendMessage,
                                     @ApiParam("是否发送短信通知") @RequestParam(defaultValue = "false") Boolean sendSms,
                                     @ApiParam("是否发送邮件通知") @RequestParam(defaultValue = "false") Boolean sendEmail) {


        if (StrUtil.isBlank(comment)) {
            comment = "";
        }
        LoginUser loginUser = JwtUtil.getLoginUser();
        taskService.addComment(id, procInstId, comment);
        OaPendingUtils.sendCompletePending(id, PendingSubStateEnum.OVERRULE.getStatus());
        // 取得流程定义
        ProcessDefinitionEntity definition = (ProcessDefinitionEntity) repositoryService.getProcessDefinition(procDefId);
        // 获取历史任务的Activity
        System.out.println(backTaskKey+"c111aoe1");
        ActivityImpl hisActivity = definition.findActivity(backTaskKey);
        // 列出所有可用活动，检查目标活动是否在其中
        List<ActivityImpl> activities = definition.getActivities();
        for (ActivityImpl activity : activities) {
            System.out.println("活动ID: " + activity);
        }

        System.out.println(hisActivity+"caoe1");
        // 实现跳转
        managementService.executeCommand(new JumpTask(procInstId, hisActivity.getId()));
        // 重新分配原节点审批人
        ActBusiness actBusiness = actBusinessService.getOne(new LambdaQueryWrapper<ActBusiness>().eq(ActBusiness::getProcInstId, procInstId).last("limit 1"));
        System.out.println("节点"+procInstId  );
        List<Task> tasks = taskService.createTaskQuery().processInstanceId(procInstId).list();
        if (tasks != null && tasks.size() > 0) {
            tasks.forEach(e -> {
                List<LoginUser> users = new ArrayList<>();
                for (String assignee : assignees.split(CommonConstant.DEFAULT_SEPARATOR)) {
                    taskService.addCandidateUser(e.getId(), assignee);
                    LoginUser toUser = sysBaseAPI.getUserByName(assignee);
                    users.add(toUser);
                    // 异步发消息
                    actZprocessService.sendMessage(actBusiness.getId(), loginUser, toUser, ActivitiConstant.MESSAGE_TODO_CONTENT
                            , "您有一个任务待审批，请尽快处理！", sendMessage, sendSms, sendEmail);
                }
                if (priority != null) {
                    taskService.setPriority(e.getId(), priority);
                    OaPendingUtils.sendRemindPendingList(loginUser, users, actBusiness.getTitle(), e.getId());
                }
            });
        }
        // 记录实际审批人员
        actBusinessService.insertHI_IDENTITYLINK(IdUtil.simpleUUID(),
                ActivitiConstant.EXECUTOR_TYPE_b, loginUser.getUsername(), id, procInstId);
        return Result.ok("操作成功");
    }

    public class JumpTask implements Command<ExecutionEntity> {

        private String procInstId;
        private String activityId;

        public JumpTask(String procInstId, String activityId) {
            this.procInstId = procInstId;
            this.activityId = activityId;
        }

        @Override
        public ExecutionEntity execute(CommandContext commandContext) {

            ExecutionEntity executionEntity = commandContext.getExecutionEntityManager().findExecutionById(procInstId);
            executionEntity.destroyScope("backed");
            ProcessDefinitionImpl processDefinition = executionEntity.getProcessDefinition();
            ActivityImpl activity = processDefinition.findActivity(activityId);
            executionEntity.executeActivity(activity);

            return executionEntity;
        }

    }

    /*已办列表*/
    @AutoLog(value = "流程-已办列表")
    @ApiOperation(value = "流程-已办列表", notes = "已办列表")
    @RequestMapping(value = "/doneList", method = RequestMethod.GET)
    public Result<Object> doneList(String name,
                                   String categoryId,
                                   Integer priority,
                                   HttpServletRequest req) {

        List<HistoricTaskVo> list = actBusinessService.getHistoricTaskVos(req, name, categoryId, priority);
        return Result.ok(list);
    }

    /*删除任务历史*/
    @AutoLog(value = "流程-删除任务历史")
    @ApiOperation(value = "流程-删除任务历史", notes = "删除任务历史")
    @RequestMapping(value = "/deleteHistoric/{ids}", method = RequestMethod.POST)
    public Result<Object> deleteHistoric(@PathVariable String ids) {

        for (String id : ids.split(CommonConstant.DEFAULT_SEPARATOR)) {
            historyService.deleteHistoricTaskInstance(id);
        }
        return Result.ok("操作成功");
    }
}
